package org.ms.mconf.sdk.spring;

import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.micro.URL;
import org.ms.mconf.sdk.MicroConfig;
import org.ms.mconf.sdk.Constants;
import org.ms.mconf.sdk.service.type.ModeType;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * The Micro Config Configuration
 *
 * @author lry
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "mconf")
public class MicroConfigConfiguration implements InitializingBean, DisposableBean {

    // ===== base config

    private Boolean enable;
    private String mode;
    private String protocol;
    private String host;
    private int port;

    // ===== system config

    private String group;
    private String node;
    private String env;
    private String application;
    private String version;

    // ===== subscribe

    private Integer subscribeCorePoolSize;
    private Integer subscribeMaximumPoolSize;
    private Long subscribeKeepAliveTime;

    // ===== redis pool

    private Integer maxIdle;
    private Integer minIdle;
    private Integer maxTotal;
    private Long timeout;
    private String password;
    private Integer database;

    @Override
    public void afterPropertiesSet() throws Exception {
        if (!enable) {
            return;
        }

        URL url = new URL(protocol, host, port, node);

        // base config
        if (StringUtils.isNotBlank(group)) {
            url.addParameter(Constants.GROUP.getName(), group);
        }
        if (StringUtils.isNotBlank(env)) {
            url.addParameter(Constants.ENV_KEY, env);
        }
        if (StringUtils.isNotBlank(application)) {
            url.addParameter(Constants.APPLICATION_KEY, application);
        }
        if (StringUtils.isNotBlank(version)) {
            url.addParameter(Constants.VERSION_KEY, version);
        }

        // subscribe config
        if (subscribeCorePoolSize != null && subscribeCorePoolSize > 0) {
            url.addParameter(Constants.SUB_EXECUTOR_CORE_POOL_SIZE.getName(), subscribeCorePoolSize);
        }
        if (subscribeMaximumPoolSize != null && subscribeMaximumPoolSize > 0) {
            url.addParameter(Constants.SUB_EXECUTOR_MAXIMUM_POOL_SIZE.getName(), subscribeMaximumPoolSize);
        }
        if (subscribeKeepAliveTime != null && subscribeKeepAliveTime > 0L) {
            url.addParameter(Constants.SUB_EXECUTOR_KEEP_ALIVE_TIME.getName(), subscribeKeepAliveTime);
        }

        // subscribe config
        if (maxIdle != null && maxIdle > 0) {
            url.addParameter(Constants.MAX_IDLE_KEY, maxIdle);
        }
        if (minIdle != null && minIdle > 0) {
            url.addParameter(Constants.MIN_IDLE_KEY, minIdle);
        }
        if (maxTotal != null && maxTotal > 0) {
            url.addParameter(Constants.MAX_TOTAL_KEY, maxTotal);
        }
        if (timeout != null && timeout > 0) {
            url.addParameter(Constants.TIMEOUT_KEY, timeout);
        }
        if (StringUtils.isNotBlank(password)) {
            url.addParameter(Constants.PASSWORD_KEY, password);
        }
        if (database != null && database >= 0) {
            url.addParameter(Constants.DATABASE_KEY, database);
        }

        if (ModeType.SERVER.toString().equals(mode)) {
            MicroConfig.OPS.initialize(url);
            MicroConfig.OPS.startup();
        } else if (ModeType.CLIENT.toString().equals(mode)) {
            MicroConfig.SDK.initialize(url);
            MicroConfig.SDK.startup();
        }
    }

    @Override
    public void destroy() throws Exception {
        if (!enable) {
            return;
        }

        if (ModeType.SERVER.toString().equals(mode)) {
            MicroConfig.OPS.destroy();
        } else if (ModeType.CLIENT.toString().equals(mode)) {
            MicroConfig.SDK.destroy();
        }
    }

}
